﻿using SHRIS.MIS.Common;
using SHRIS.MIS.Common.Model;
using SHRIS.MIS.Common.Util.Extension;
using SHRIS.MIS.Entity.LonginState;
using SHRIS.MIS.Entity.SystemManage;
using SHRIS.MIS.IService.SystemManage;
using SHRIS.MIS.Model.Param.SystemManage;
using SHRIS.MIS.Model.Result;
using SHRIS.MIS.Service.SystemManage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SHRIS.MIS.Business.SystemManage
{
    public class DepartmentBLL
    {
        private IDepartmentService _departmentService;
        private IUserService _userService;

        public DepartmentBLL(IDepartmentService departmentService, IUserService userService)
        {
            _departmentService = departmentService;
            _userService = userService;
        }

        #region 获取数据
        public async Task<TEntity<List<DepartmentEntity>>> GetList(DepartmentListParam param)
        {
            TEntity<List<DepartmentEntity>> obj = new TEntity<List<DepartmentEntity>>();
            obj.Data = await _departmentService.GetList(param);
            OperatorInfo operatorInfo = await Operator.Instance.Current();
            if (operatorInfo.IsSystem != 1)
            {
                List<Guid> childrenDepartmentIdList = await GetChildrenDepartmentIdList(obj.Data, operatorInfo.DepartmentId.Value);
                obj.Data = obj.Data.Where(p => childrenDepartmentIdList.Contains(p.Id.Value)).ToList();
            }
            List<UserEntity> userList = await _userService.GetList(new UserListParam { UserIds = string.Join(",", obj.Data.Select(p => p.PrincipalId).ToArray()) });
            foreach (DepartmentEntity entity in obj.Data)
            {
                if (entity.PrincipalId.HasValue && entity.PrincipalId.Value != Guid.Empty)
                {
                    entity.PrincipalName = userList.Where(p => p.Id.Value == entity.PrincipalId.Value).Select(p => p.RealName).FirstOrDefault();
                }
                else
                {
                    entity.PrincipalName = string.Empty;
                }
            }
            obj.Tag = 1;
            return obj;
        }

        public async Task<TEntity<List<ZtreeInfo>>> GetZtreeDepartmentList(DepartmentListParam param)
        {
            var obj = new TEntity<List<ZtreeInfo>>();
            obj.Data = new List<ZtreeInfo>();
            List<DepartmentEntity> departmentList = await _departmentService.GetList(param);
            OperatorInfo operatorInfo = await Operator.Instance.Current();
            if (operatorInfo.IsSystem != 1)
            {
                List<Guid> childrenDepartmentIdList = await GetChildrenDepartmentIdList(departmentList, operatorInfo.DepartmentId.Value);
                departmentList = departmentList.Where(p => childrenDepartmentIdList.Contains(p.Id.Value)).ToList();
            }
            foreach (DepartmentEntity department in departmentList)
            {
                obj.Data.Add(new ZtreeInfo
                {
                    id = department.Id,
                    pId = department.ParentId,
                    name = department.DepartmentName
                });
            }
            obj.Tag = 1;
            return obj;
        }

        public async Task<TEntity<List<ZtreeInfo>>> GetZtreeUserList(DepartmentListParam param)
        {
            var obj = new TEntity<List<ZtreeInfo>>();
            obj.Data = new List<ZtreeInfo>();
            List<DepartmentEntity> departmentList = await _departmentService.GetList(param);
            OperatorInfo operatorInfo = await Operator.Instance.Current();
            if (operatorInfo.IsSystem != 1)
            {
                List<Guid> childrenDepartmentIdList = await GetChildrenDepartmentIdList(departmentList, operatorInfo.DepartmentId.Value);
                departmentList = departmentList.Where(p => childrenDepartmentIdList.Contains(p.Id.Value)).ToList();
            }
            List<UserEntity> userList = await _userService.GetList(null);
            foreach (DepartmentEntity department in departmentList)
            {
                obj.Data.Add(new ZtreeInfo
                {
                    id = department.Id,
                    pId = department.ParentId,
                    name = "部门：" + department.DepartmentName
                });
                List<Guid> userIdList = userList.Where(t => t.DepartmentId == department.Id).Select(t => t.Id.Value).ToList();
                foreach (UserEntity user in userList.Where(t => userIdList.Contains(t.Id.Value)))
                {
                    obj.Data.Add(new ZtreeInfo
                    {
                        id = user.Id,
                        pId = department.Id,
                        name = user.RealName
                    });
                }
            }
            obj.Tag = 1;
            return obj;
        }

        public async Task<TEntity<DepartmentEntity>> GetEntity(Guid id)
        {
            TEntity<DepartmentEntity> obj = new TEntity<DepartmentEntity>();
            obj.Data = await _departmentService.GetEntity(id);
            obj.Tag = 1;
            return obj;
        }

        public async Task<TEntity<int>> GetMaxSort()
        {
            TEntity<int> obj = new TEntity<int>();
            obj.Data = await _departmentService.GetMaxSort();
            obj.Tag = 1;
            return obj;
        }
        #endregion

        #region 提交数据
        public async Task<TEntity<string>> SaveForm(DepartmentEntity entity)
        {
            TEntity<string> obj = new TEntity<string>();
            if(entity.ParentId == null || entity.ParentId == Guid.Empty)
            {
                obj.Message = "上级部门不能为空";
                return obj;
            }
            if (entity.PrincipalId == null || entity.PrincipalId == Guid.Empty)
            {
                obj.Message = "责任人不能为空";
                return obj;
            }
            if (_departmentService.ExistDepartmentName(entity))
            {
                obj.Message = "部门名称已经存在！";
                return obj;
            }
            var user =await _userService.GetEntity(entity.PrincipalId.Value);
            if(user == null)
            {
                obj.Message = "责任人不能选择部门";
                return obj;
            }
            await _departmentService.SaveForm(entity);
            obj.Data = entity.Id.ParseToString();
            obj.Tag = 1;
            return obj;
        }

        public async Task<TEntity> DeleteForm(string ids)
        {
            TEntity obj = new TEntity();
            string[] idArr = TextHelper.SplitToArray<string>(ids, ',');
            var guidIdList = Array.ConvertAll(idArr, x => Guid.Parse(x));
            foreach (Guid id in guidIdList)
            {
                if (_departmentService.ExistChildrenDepartment(id))
                {
                    obj.Message = "该部门下面有子部门！";
                    return obj;
                }
            }
            await _departmentService.DeleteForm(ids);
            obj.Tag = 1;
            return obj;
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 获取当前部门及下面所有的部门
        /// </summary>
        /// <param name="departmentList"></param>
        /// <param name="departmentId"></param>
        /// <returns></returns>
        public async Task<List<Guid>> GetChildrenDepartmentIdList(List<DepartmentEntity> departmentList, Guid departmentId)
        {
            if (departmentList == null)
            {
                departmentList = await _departmentService.GetList(null);
            }
            List<Guid> departmentIdList = new List<Guid>();
            departmentIdList.Add(departmentId);
            GetChildrenDepartmentIdList(departmentList, departmentId, departmentIdList);
            return departmentIdList;
        }
        #endregion 

        #region 私有方法
        /// <summary>
        /// 获取该部门下面所有的子部门
        /// </summary>
        /// <param name="departmentList"></param>
        /// <param name="departmentId"></param>
        /// <param name="departmentIdList"></param>
        private void GetChildrenDepartmentIdList(List<DepartmentEntity> departmentList, Guid departmentId, List<Guid> departmentIdList)
        {
            var children = departmentList.Where(p => p.ParentId == departmentId).Select(p => p.Id.Value).ToList();
            if (children.Count > 0)
            {
                departmentIdList.AddRange(children);
                foreach (Guid id in children)
                {
                    GetChildrenDepartmentIdList(departmentList, id, departmentIdList);
                }
            }
        }
        #endregion
    }
}
